package main

import (
	"fmt"
	"sync"
	"time"
)

/**
全局变量,多线程下出现资源竞争问题,代码会出现错误
fatal error: concurrent map writes
解决方式 加入互斥锁
运行时 在编译时 增加参数-race 可以查看是否存在资源竞争问题.
go run -race xxx.go
出现有2个存在竞争关系
Found 2 data race(s)

通过互斥锁解决
在使用写锁时,读数据也会出现Found 2 data race(s), 但是在读写锁就不会出现.


*/
var (
	mapRes = make(map[int]uint64)
	/**
	声明全局的互斥锁
	lock是一个全局的互斥锁
	Mutex 互斥

	*/
	lock = sync.Mutex{}
)

func calculate(n int) {

	var res uint64 = 1
	for i := 1; i <= n; i++ {
		res *= uint64(i)
	}

	// 加锁
	lock.Lock()
	mapRes[n] = res
	// 解锁
	defer lock.Unlock()
}

func main() {
	for i := 0; i < 20; i++ {
		// fatal error: concurrent map writes
		go calculate(i)
	}

	time.Sleep(time.Second * 1)
	lock.Lock()
	fmt.Printf("mapRes size =%v \n", len(mapRes))
	fmt.Printf("mapRes=%v \n", mapRes)
	lock.Unlock()

}
